package com.yqg.protection.netty.handler;

import com.yqg.protection.netty.service.Sdf300Service;
import com.yqg.protection.utils.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
@Component
@ChannelHandler.Sharable
public class Sdf300Handler extends AbstractProtocolHandler implements DynamicProtocolHandler {

    @Autowired
    private Sdf300Service sdf300Service;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        try {
            if (msg instanceof ByteBuf) {
                ByteBuf buf = (ByteBuf) msg;
                // 将ByteBuf转换为十六进制字符串
                String hexData = ByteBufUtil.hexDump(buf).toUpperCase();
                log.info("收到SDF300原始数据: {}", hexData);

                // 创建ProtocolData对象
                ProtocolData protocolData = new ProtocolData();
                protocolData.setHeader(hexData.substring(0,2));
                protocolData.setRawData(hexData);
                protocolData.setCtx(ctx);
                protocolData.setSaveTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

                // 生成并发送响应
                byte[] response = generateResponse(protocolData);
                ctx.writeAndFlush(Unpooled.wrappedBuffer(response));
                log.info("已发送FE协议响应");

                // 调用处理逻辑
                handle(protocolData);
            } else {
                log.warn("收到非ByteBuf类型数据: {}", msg.getClass().getName());
                ctx.fireChannelRead(msg);
            }
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    public void handle(ProtocolData data) {
        String frame = data.getRawData();
        try {
            if (!frame.startsWith("FE")) {
                log.warn("非SDF300数据包，帧头: {}", frame.substring(0, 2));
                return;
            }
            // LEN字段是2字节（4个十六进制字符），表示DATA部分的字节长度
            int dataLenFromHeader = Integer.parseInt(frame.substring(2, 6), 16);

            // 计算实际DATA部分的字节长度：总字符串长度 - 帧头(2) - LEN(4) - CRC(4)，再除以2（每个字节对应2个字符）
            int actualDataLen = (frame.length() - 2 - 4 - 4) / 2;

            // 3. 验证DATA部分长度
            if (dataLenFromHeader != actualDataLen) {
                log.error("DATA部分长度不匹配，期望:{}字节，实际:{}字节", dataLenFromHeader, actualDataLen);
                return;
            } else {
                log.info("DATA部分长度匹配成功，期望:{}字节，实际:{}字节", dataLenFromHeader, actualDataLen);
            }
            // 完整帧总字节数 = 1(HEADER) + 2(LEN) + dataLenFromHeader(DATA) + 2(CRC)
            int expectedTotalBytes = 1 + 2 + dataLenFromHeader + 2;
            int actualTotalBytes = frame.length() / 2; // 十六进制字符串长度 / 2 = 字节数
            if (expectedTotalBytes != actualTotalBytes) {
                log.error("总帧长度不匹配，期望:{}字节，实际:{}字节", expectedTotalBytes, actualTotalBytes);
                return;
            }
            // 4. 解析CTR（1字节）：DATA LEN之后的8-9字符（19）
            String ctrHex = frame.substring(8, 10); // "19"
            int ctr = Integer.parseInt(ctrHex, 16);
            log.info("CTR:{}（数据域,无需应答,通信正常,定时上报,ID寻址）", ctrHex);

            // 5. 解析ADDR（IMEI，ASCII）：CTR之后的10-73字符（38...00共32字符=16字节）
            /* 设备 ID 寻址时，ADDR 长度为 16 个字节，ID 类型可选 IMEI，IMSI，UID 三
                种。当类型选择为 IMEI/IMSI 时，前 15 个字节为 ASCII 码，最后一个字节
                若为 0 则代表是设备本身，若为 01-99 则代表设备所连接的终端节点。*/
            String addrHex = frame.substring(10, 42); // 16字节→32字符
            String imei = hexToAscii(addrHex).substring(0, 15); // 转换为ASCII：867900047083657
            log.info("IMEI:{}", imei);

            // 6. 解析DIO（1字节）：ADDR之后的74-75字符（03）
            String dioHex = frame.substring(42, 44); // "03"
            log.info("DIO:{}（SDF300设备）", dioHex);

            // 7. 解析DII（1字节）：DIO之后的76-77字符（11）
            String diiHex = frame.substring(44, 46); // "11"
            log.info("DII:{}（三相,有电能,无谐波）", diiHex);

            // 8. 提取VALUE部分
            String value = frame.substring(42, frame.length() - 4);

            // 9. 异步处理数据
            executor.execute(() -> dataSaver.saveDataToFileAsync(frame, new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date()), imei));
            executor.execute(() -> sdf300Service.analyzeSdf300Data(value, imei, data.getSaveTime()));

        } catch (Exception e) {
            log.error("SDF300数据处理异常: {}", e.getMessage(), e);
        }
    }

    // 十六进制字符串转ASCII (过滤空字符)
    private String hexToAscii(String hex) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < hex.length(); i += 2) {
            String byteStr = hex.substring(i, i + 2);
            char c = (char) Integer.parseInt(byteStr, 16);
            sb.append(c);
        }
        return sb.toString();
    }

    // 生成响应方法保持不变
    public byte[] generateResponse(ProtocolData data) {
        String raw = data.getRawData();
        String header = data.getHeader();
        String src = raw.substring(8, 38);
        String cmd = raw.substring(38, 40);
        return generateSdf300Response(header, src, cmd);
    }

    @Override
    public String supportHeader() {
        return "FE";
    }

    private byte[] generateSdf300Response(String header, String src, String cmd) {
        String response = header + "0002" + src + cmd + "AA55";
        return ByteUtil.toBytes(response);
    }
}
